package com.woniuxy;

import java.util.HashMap;

/**
 * @Author: 马宇航
 * @Todo: 学习HashMap
 * @DateTime: 22/04/01/0001 上午 9:39
 * @Component: 成都蜗牛学苑
 **/
public class HashMapStudy {
    public static void main(String[] args) {
        /*1.Hash表 ---> 散列表
        *    Hash表就是一个单纯用数组实现的一个表。可以理解为就是一个纯数组。
        *    为什么叫Hash，因为这个数组存放数据的时候，这个数据是需要经过一个Hash计算，计算后的值，根据一定的算法，存入数组中。
        *   Hash算法的宗旨：要设计一个很牛逼的Hash算法，让我的数据，尽量不发生冲突，然后能够均匀分布在整个Hash表中。
        * 2.什么是Hash碰撞，数据经过Hash运算后，计算的下标，出现多个元素同一个下标的情况，这个叫做Hash碰撞，也叫作Hash冲突。
        * 3.怎么解决Hash碰撞？
        *   3.1 开放寻址法-线性探测法：+-1d  (d=1,2,3,4等差数列)
        *   3.2 开放寻址法-二次探测法：+-1d  (d=1,2,4,8等比数列)
        *   3.3 双重散列法： hi=(h(key)+ i*h1(key))%m  (0≤i≤m-1)  //即di=i*h1(key);
        *   3.4 拉链法(链表法)：如果出现冲突，就拼接成链表！
        * 4.HashMap使用的是 拉链法！
        * 5.HashMap的Hash算法(下标计算方式)，绝对不是取模！
        *       0000 0111
        *       xxxx xxxx  目标值经过hash计算后的结果  位或 或者 位于
        * ——————————————————
        * 位或  xxxx x111   不行，无法使用这种来当做下标的计算方式
        * 位于  0000 0xxx   ==> 这个未知数换成10进制，结果只能是：0~7
        *   HashMap下标计算方式：hash(key)&(HashMap的长度-1)
        * 6.HashMap的数据结构来源：基本是基于数组来实现的一个Hash表，这个查询速度很快，但是会出现Hash碰撞冲突，解决冲突的办法就是使用链表
        *                    如果链表太长了，又会出现一个问题，链表查询需要一个一个的查速度太慢，引入了红黑树，提高链表的查询速度，降低了新增删除速度。
        * 7. put方法：按照CRUD的方式来进行学习.
        *     7.1 第一次放入数据的时候，我们的HashMap实际上是空的null。
        *         源码在：  if ((tab = table) == null || (n = tab.length) == 0){n = (tab = resize()).length;}
        *                  判断 HashMap是不是空的，空的，则是第一次放入数据，此时需要调用 resize()方法进行扩容(极度重要)！
        *                  第一次扩容：是从0-->16 如果没有设置容量或者阈值的时候，都是默认值。
        *     7.2 第一次放入数据的时候，扩容完成后，继续执行下一个判断
        *           源码： if ((p = tab[i = (n - 1) & hash]) == null){tab[i] = newNode(hash, key, value, null);}
        *                 判断当前数组对应下标上有没有数据，如果是null没有数据，则直接newNode节点，然后 tab[i] = 第一个节点的地址

        *
        */

    }
}
